#include <iostream>
#include <string>
#include <etcd/Client.hpp>
#include <etcd/Response.hpp>
#include <etcd/KeepAlive.hpp>
#include <etcd/Watcher.hpp>
#include <etcd/Value.hpp>
#include <thread>

int main()
{
    std::string host_url = "http://127.0.0.1:2379";
    //实例化客户端对象
    etcd::Client client (host_url);
    /*获取指定的键值对信息---etcd服务器不止对键值对进行存储，还以目录的方式管理键值对，
    比如/service/user 和 /service/data 中 user和data都在service目录下*/
    pplx::task<etcd::Response> pplx_resp = client.ls("/service");//这样就可以将service目录下的所有key都获取到
    etcd::Response resp = pplx_resp.get();
    if(!resp.is_ok())
    {
        std::cout << "获取键值对数据失败： " << resp.error_message() << std::endl;
        return -1;
    }
    //ls方法会一次性获取多个数据，所以可以遍历打印
    int sz = resp.keys().size();
    for(int i = 0; i < sz; ++i)
    {
        std::cout << resp.value(i).as_string() << "可以提供" << resp.key(i) << "服务" << std::endl;
    }
    //实例化一个键值对事件监控对象
    etcd::Watcher watcher(client, "/service", [&](const etcd::Response& resp)->void{
        if(!resp.is_ok())
        {
            std::cout << "收到一个错误的事件通知：" << resp.error_message() << std::endl;
            return;
        }
        for(auto const& ev : resp.events())
        {
            if(ev.event_type() == etcd::Event::EventType::PUT)
            {
                std::cout << "服务信息发生了改变： " << std::endl;
                std::cout << "当前的值： " << ev.kv().key() << "-" << ev.kv().as_string() << std::endl;
                std::cout << "原来的值： " << ev.prev_kv().key() << "-" << ev.prev_kv().as_string() << std::endl;
            }
            else if(ev.event_type() == etcd::Event::EventType::DELETE_)
            {
                std::cout << "服务信息下线被删除：" << std::endl;
                std::cout << "当前的值： " << ev.kv().key() << "-" << ev.kv().as_string() << std::endl;
                std::cout << "原来的值： " << ev.prev_kv().key() << "-" << ev.prev_kv().as_string() << std::endl;
            }
        }
    }, true);
    watcher.Wait();
    return 0;
}
